package a02;

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class RegularControl<M> extends JPanel {

    private static final long serialVersionUID = 1L;
    private RegularBoard<M> board;
    private JFrame frame;
    private RegularGame<M> game;

    private boolean gameMode1Player = false;

    private MainMenu<M> menu;
    SaveGameManager<M> saveman;
    private Stack<RegularGame<M>> stack;

    public RegularControl(RegularGame<M> game) {
	this(game, new RegularBoard<M>(game), "Kein Fenstername", 0);
    }

    public RegularControl(RegularGame<M> game, RegularBoard<M> b, String title,
	    int kiLevel) {
	this.saveman = new SaveGameManager<M>(this);
	this.menu = new MainMenu<M>(this);
	this.stack = new Stack<RegularGame<M>>();
	this.frame = this.menu.getNewFrame(title);
	this.setName(title);
	this.frame.add(this.menu.getPanel(kiLevel));
	this.setGame(game);
	this.setBoard(b);
	this.getBoard().addMouseListener(new MouseAdapter() {
	    @Override
	    public void mousePressed(MouseEvent ev) {		
		byte c = (byte) (ev.getPoint().getX() / RegularControl.this
			.getBoard().getUNIT());
		byte r = (byte) (ev.getPoint().getY() / RegularControl.this
			.getBoard().getUNIT());
		RegularControl.this.whenMousePressed(c, r);
	    }
	});

	this.add(this.getBoard());

	this.frame.setMaximumSize(new Dimension(600, 660));
	this.frame.setMinimumSize(new Dimension(350, 350));
	this.frame.pack();
	this.frame.setLocationRelativeTo(null);
	this.frame.setResizable(false);
	refresh();
	this.frame.setVisible(true);
    }

    public RegularControl(RegularGame<M> game, String title) {
	this(game, new RegularBoard<M>(game), title, 0);
    }

    public RegularControl(RegularGame<M> game, String title, int kiLevel) {
	this(game, new RegularBoard<M>(game), title, kiLevel);
    }

    public void clearStack() {
	this.stack.clear();
	this.menu.setButtonEnabled(false);
    }

    public void close() {
	this.frame.dispose();
    }

    public RegularBoard<M> getBoard() {
	return this.board;
    }

    public RegularGame<M> getGame() {
	return this.game;
    }

    public MainMenu<M> getMenu() {
	return this.menu;
    }

    public RegularGame<M> getNewGame() {
	System.out.println("reset aus regularcontrol");
	return null;
    }

    public SaveGameManager<M> getSaveGameManager() {
	return this.saveman;
    }

    public Stack<RegularGame<M>> getStack() {
	return this.stack;
    }

    public boolean isGameMode1Player() {
	return this.gameMode1Player;
    }

    public void refresh() {
	this.menu.setStatus("Spieler "
		+ this.getBoard().getPlayerColorName(
			this.getBoard().getGame().currentPlayer())
		+ " ist an der Reihe");
    }

    public void reset() {
	RegularGame<M> game = this.getNewGame();
	if (!(game == null)) {
	    this.getBoard().setGame(game);
	}
	this.clearStack();
	refresh();
    }

    public void setBoard(RegularBoard<M> board) {
	this.board = board;
    }

    private void setGame(RegularGame<M> game) {
	this.game = game;
    }

    public void setGameMode1Player(boolean gameMode1Player) {
	this.gameMode1Player = gameMode1Player;
    }

    public void setStatus(String status) {
	this.menu.setStatus(status);
    }

    public void showPopup(String title, String message) {
	JOptionPane.showMessageDialog(this, message, title, 1);
    }

    public void undo() {
	this.getBoard().setGame(this.stack.pop());
	if (this.stack.isEmpty()) {
	    this.menu.setButtonEnabled(false);
	}
	refresh();
    }

    public void whenMousePressed(byte c, byte r) {
	if (this.getBoard().getGame().ended()) {
	    return;
	}
	if (this.getBoard().getGame().getAtPosition(c, r) != this.getBoard()
		.getGame().getPlayerNone()) {
	    return;
	}
	RegularGame<M> newState = this.getBoard().getGame().setAtPosition(c, r);
	this.stack.push(this.getBoard().getGame());
	this.getBoard().setGame(newState);
	refresh();

	if (this.getBoard().getGame().ended()) {
	    this.menu.setStatus("Spiel beendet! ");
	    if (this.getBoard()
		    .getGame()
		    .wins(this
			    .getBoard()
			    .getGame()
			    .otherPlayer(
				    this.getBoard().getGame().currentPlayer()))) {
		this.showPopup(
			"GEWONNEN",
			"Spieler "
				+ this.getBoard()
					.getPlayerColorName(
						this.getBoard()
							.getGame()
							.otherPlayer(
								this.getBoard()
									.getGame()
									.currentPlayer()))
				+ " hat gewonnen!");
	    } else {
		this.showPopup("GEWONNEN", "Leider unentschieden!");
	    }

	}
	if (!this.stack.isEmpty()) {
	    this.menu.setButtonEnabled(true);
	}

    }

}
